#include "visit.h"


/*!
 *@brief 访问一元表达式
 *@param node AST节点指针
 *@param s 符号表指针
 *@param m 模块指针
 *@param bb 基本块指针
 *@return variant<int, float, string>类型

 * 其中int和float是可能的整数或小数

 * string类型是标识符
 *@note 使用
    if(auto pval = std::get_if<int>(&v))
        int value = *pval;
    else if(auto pval = std::get_if<float>(&v))
        float value = *pval;
    else
        string ident = *pval;
 */
variant<int, float, string> visit_unaryExp(ASTNode* node, SymbolTable* s, Module* m, BasicBlock* bb) {
    if (!node){
        variant<int, float, string> res;
        res = 0;
        return res;
    }

    ASTNode* child = node->children[0];
    if (child->type == "unaryOp") {
        // 处理一元操作符
        visit_unaryOp(node->children[0], s, bb);
        visit_unaryExp(node->children[1], s, m, bb);
    } else if (child->type == "primaryExp") {
        // 处理基本表达式
        variant<int, float, string> res = visit_primaryExp(node->children[0], s, bb);
        return res;
    } else if(child->type == "Ident"){
        string ident = visit_Ident(node->children[0], s, bb);

        Symbol* symbol_ident = s -> lookup(ident);
        if(symbol_ident -> kind == VAR || symbol_ident -> kind == CONST){
            if(symbol_ident -> type == "int"){
                // LoadInst::create_load(m->get_int32_type(), symbol_ident->alloc, bb);
                variant<int, float, string> res = ident;
                return res;
            }
            else if(symbol_ident -> type == "float"){
                // LoadInst::create_load(m->get_float_ptr_type(), symbol_ident->alloc, bb);
                variant<int, float, string> res = ident;
                return res;
            }
            else {
                std::cerr << "visit_unaryExp :" << "不支持的类型: " << symbol_ident -> type << std::endl;
                throw std::invalid_argument(string("visit_unaryExp :") + "不支持的类型: " + symbol_ident -> type);
            }
            
        }
        else if(symbol_ident -> kind == FUNC){
            visit_callFunc(node->children[1], s, bb);
        }
        else {
            std::cerr << "visit_unaryExp :" << "不支持的类型: " << symbol_ident -> kind << std::endl;
            throw std::invalid_argument(string("visit_unaryExp :") + "不支持的类型: " + to_string(symbol_ident -> kind));
        }

        
    }
}